home *** CD-ROM | disk | FTP | other *** search
- Subject: v09i028: A TECO text editor, Part01/04
- Newsgroups: mod.sources
- Approved: rs@mirror.TMC.COM
-
- Submitted by: genrad!mlf
- Mod.sources: Volume 9, Issue 28
- Archive-name: teco/Part01
-
-
- This is TECO for Ultrix, part 1. It consists of nine files:
- manpage.doc (the "man" page), teco.doc (an overview of what it is),
- maketeco.doc (how to build it), teco_data.doc (once through TECO's
- data storage), makefile, .tecorc (an example of the startup file)
- te_defs.h (header file), te_data.c (global data), te_main.c (main).
-
- [ I diddled with the Makefile a bit, renamed .tecorc to dot.tecorc,
- and packed things up into shell archives. Better documentation
- is encouraged -- any "old-timers" wanna write it? -- as would be
- support for TERMCAP or CURSES; send changes to genrad!mlf --r$ ]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If this archive is complete, you will see the message:
- # "End of archive 1 (of 4)."
- # Contents: MANIFEST Makefile dot.tecorc maketeco.doc manpage.doc
- # te_data.c te_exec0.c te_main.c te_rdcmd.c te_utils.c teco.doc
- # teco_data.doc
- # Wrapped by rs@mirror on Thu Mar 12 19:54:25 1987
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo shar: Extracting \"MANIFEST\" \(684 characters\)
- if test -f MANIFEST ; then
- echo shar: Will not over-write existing file \"MANIFEST\"
- else
- sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1 This shipping list
- X Makefile 1
- X dot.tecorc 1
- X maketeco.doc 1
- X manpage.doc 1
- X te_chario.c 2
- X te_data.c 1
- X te_defs.h 2
- X te_exec0.c 1
- X te_exec1.c 3
- X te_exec2.c 3
- X te_main.c 1
- X te_rdcmd.c 1
- X te_srch.c 2
- X te_subs.c 2
- X te_utils.c 1
- X te_window.c 4
- X teco.doc 1
- X teco_data.doc 1
- END_OF_MANIFEST
- if test 684 -ne `wc -c <MANIFEST`; then
- echo shar: \"MANIFEST\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"Makefile\" \(518 characters\)
- if test -f Makefile ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- X##
- X## TECO MAKEFILE
- X##
- X
- X# Debugging or optimizing?
- X#CFLAGS = -g
- XCFLAGS = -O
- XTERMCAP = -ltermcap
- X
- XOBJECTS = te_data.o te_exec0.o te_exec1.o te_exec2.o te_main.o te_rdcmd.o \
- X te_srch.o te_subs.o te_utils.o te_window.o
- X
- Xte: $(OBJECTS) te_chario.o
- X $(CC) -o te $(CFLAGS) $(OBJECTS) te_chario.o $(TERMCAP)
- X
- Xtex: $(OBJECTS) te_chx.o
- X $(CC) -o tex $(CFLAGS) $(OBJECTS) te_chx.o $(TERMCAP)
- X
- X$(OBJECTS) te_chario.o te_chx.o: te_defs.h
- Xte_chx.o: te_chario.c
- X cp te_chario.c te_chx.c
- X $(CC) -DDEBUG $(CFLAGS) -c te_chx.c
- X
- END_OF_Makefile
- if test 518 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"dot.tecorc\" \(259 characters\)
- if test -f dot.tecorc ; then
- echo shar: Will not over-write existing file \"dot.tecorc\"
- else
- sed "s/^X//" >dot.tecorc <<'END_OF_dot.tecorc'
- X!!!!!! THIS IS A SAMPLE FILE. REPLACE ^[ with ESCAPE, and ^A/^E with
- X!!!!!! THEIR REAL CONTROL CHARACTERS, AND DELETE THESE TWO LINES.
- X@ei// hk 64ez :qz-3"g gz j:s ^["s
- X0k hxz hk
- X:eb^Eqz^[ "e
- X^AFile not found: ^A :g* ^A
- X^A hkekex '
- Xy'' 5,7:w 0,0xz
- X^[^[
- END_OF_dot.tecorc
- if test 259 -ne `wc -c <dot.tecorc`; then
- echo shar: \"dot.tecorc\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"maketeco.doc\" \(2478 characters\)
- if test -f maketeco.doc ; then
- echo shar: Will not over-write existing file \"maketeco.doc\"
- else
- sed "s/^X//" >maketeco.doc <<'END_OF_maketeco.doc'
- XTECO for Ultrix Matt Fichtenbaum 3/27/86 revised 7/25/86
- X
- X These notes describe briefly what it is and how to make it.
- X
- X Ultrix TECO is an editor that is mostly compatible with DEC
- XStandard TECO. It is written in C to run under Ultrix (and other
- XUnix (tm) implementations, e.g., it has compiled and run on a Sun
- Xworkstation). It implements all the editor functions of DEC TECO
- Xand it has some additional features suited to the Unix environment,
- Xsuch as the ability to execute Unix commands or to pass text from
- XTECO's buffer through a Unix process and incorporate the result
- Xinto the text buffer. It lacks some of the display support features
- Xof Standard TECO, but includes the split-screen "window" mode
- Xsuitable for using "raw" TECO.
- X
- X Note that TECO's CRT routines are hard-coded for a VT100-type
- Xterminal. Using another type of terminal requires changing these
- Xroutines.
- X
- X Ultrix TECO consists of twelve source files:
- X
- X te_defs.h definitions file #include'd by the .c files
- X te_data.c "common" data
- X te_main.c main program
- X te_rdcmd.c read commands and build the command string
- X te_exec0.c exec commands 1 (initial dispatch & expressions)
- X te_exec1.c exec commands 2 (most commands)
- X te_exec2.c exec commands 3 (E, F commands, file I/O, Unix extensions)
- X te_srch.c search operations
- X te_window.c CRT display routines
- X te_chario.c terminal I/O, interaction with tty driver, signals
- X te_subs.c higher level subroutines
- X te_utils.c lower level subroutines
- X
- XTECO is built as follows:
- X
- X 1. Compile all the .c files with cc -c -O <file>.c
- X
- X 2. Link all the object files with cc -o te *.o
- X
- XNote that TECO catches the "interrupt" (^C) signal; this may cause problems when
- Xusing dbx. This can be circumvented by compiling te_chario.c with the symbol
- XDEBUG defined, i.e.,
- X
- X cc -c -g -DDEBUG te_chario.c
- X
- X(naturally, the -g flag should be specified to all the cc commands
- Xif dbx is to be used).
- X
- X
- XThere are two 'makefiles.' 'makefile' makes 'te' as above; 'makefile.x'
- Xmakes 'te' and 'tex' for use with dbx. 'tex' compiles te_chario.c with
- Xthe DEBUG flag set. Because 'makefile.x' compiles with -g and 'makefile'
- Xdoesn't, the two ought not to share the same directory.
- X
- XNOTE: makefile.x is set up to make the -DDEBUG version of te_chario.o
- Xunder the name te_chx.o. The source directory should contain te_chx.c
- Xas a symbolic link to te_chario.c.
- X
- X The file .tecorc illustrates one possible startup. It implements
- X'te file' to mean
- X
- X %te
- X *ebfile$y5,7:w$$
- X
- END_OF_maketeco.doc
- if test 2478 -ne `wc -c <maketeco.doc`; then
- echo shar: \"maketeco.doc\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"manpage.doc\" \(1285 characters\)
- if test -f manpage.doc ; then
- echo shar: Will not over-write existing file \"manpage.doc\"
- else
- sed "s/^X//" >manpage.doc <<'END_OF_manpage.doc'
- XNAME
- X te - TECO text editor
- X
- XSYNOPSIS
- X te [filename]
- X
- XDESCRIPTION
- X te is an implementation of TECO written in C to run under
- X Ultrix 1.2.
- X
- X te implements DEC standard TECO, with some exceptions
- X described below, plus some extensions for the Ultrix
- X environment.
- X
- X te assumes a VT100-type terminal, and its display
- X driver is hard-coded for such.
- X
- XDOCUMENTATION
- X The DEC Standard TECO book describes the basic editing
- X functions of TECO. teco.doc describes the differences
- X between te and standard TECO, including the extensions
- X for the Ultrix environment. maketeco.doc describes the
- X files that comprise te, and the build procedure.
- X
- XFILES
- X ~/.tecorc editor startup file
- X <file>.tmp temporary output file(s)
- X <file>.bak previous version of edited file
- X /etc/termcap describes terminal (used only to find width of VT100)
- X
- XAUTHOR
- X Matt Fichtenbaum, GenRad Inc., Concord, Mass.
- X
- XBUGS
- X te acquires memory for its buffer using malloc(), but
- X never returns the space. This can cause the task in
- X memory to appear to be larger than it is.
- X
- X Several of the standard display features of TECO, most
- X notably the -256+n:W command used by interpretive editing
- X macros, are unimplemented. There are undoubtedly some
- X subtle bugs in the display handler for the features that
- X are implemented.
- X
- END_OF_manpage.doc
- if test 1285 -ne `wc -c <manpage.doc`; then
- echo shar: \"manpage.doc\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_data.c\" \(7350 characters\)
- if test -f te_data.c ; then
- echo shar: Will not over-write existing file \"te_data.c\"
- else
- sed "s/^X//" >te_data.c <<'END_OF_te_data.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_data.c global variables 12/31/85 */
- X
- X#include "te_defs.h"
- X
- X/* error message text */
- Xchar *errors[] =
- X {
- X "> not in iteration",
- X "Can't pop Q register",
- X "Can't open output file ",
- X "File not found ",
- X "Invalid E character",
- X "Invalid F character",
- X "Invalid insert arg",
- X "Invalid command",
- X "Invalid number",
- X "Invalid P arg",
- X "Invalid \" character",
- X "Invalid Q-reg name",
- X "Invalid radix arg",
- X "Invalid search arg",
- X "Invalid search string",
- X "Invalid ^ character",
- X "Insufficient memory available",
- X "Missing )",
- X "No arg before ^_",
- X "No arg before ,",
- X "No arg before =",
- X "No arg before )",
- X "No arg before \"",
- X "No arg before ;",
- X "No arg before U",
- X "No file for input",
- X "No file for output",
- X "Numeric arg with Y",
- X "Output file already open",
- X "Pushdown list overflow",
- X "Pointer off page",
- X "; not in iteration",
- X "Search failure ",
- X "String too long",
- X "Unterminated command",
- X "Unterminated macro",
- X "Execution interrupted",
- X "Y command suppressed",
- X "Invalid W arg",
- X "Numeric arg with FR",
- X "Internal error",
- X "EOF read from std input",
- X "Invalid A arg",
- X "Ambiguous file specification ",
- X "System fork or pipe error"
- X } ;
- X/* declare global variables */
- X struct buffcell *freebuff = NULL; /* buffcell free-list pointer */
- X struct buffcell *dly_freebuff = NULL; /* delayed free-list pointer */
- X struct qp *freedcell = NULL; /* cell free-list pointer */
- X
- X/* the text buffer header */
- X struct qh buff = { NULL, NULL, 0, 0 } ;
- X
- X/* the q-register headers point to the start of the buffer and registers */
- X struct qh qreg[NQREGS+5]; /* for q regs, command, search, file, sys-command, time/date */
- X
- X/* the q-register stack contains temporary copies of q-register contents */
- X struct qh qstack[QSTACKSIZE]; /* q-reg stack */
- X struct qh *qsp; /* q-reg stack pointer */
- X
- X/* the macro stack contains pointers to the currently active macros. */
- X/* the top of the stack is the command pointer */
- X struct qp mstack[MSTACKSIZE]; /* macro stack */
- X struct qp *msp; /* macro stack pointer */
- X
- X/* the expression stack */
- X struct exp_entry estack[ESTACKSIZE]; /* expression stack */
- X struct exp_entry *esp; /* expression stack pointer */
- X
- X/* global variables, etc. */
- X
- Xint char_count = 0; /* char count for tab typer */
- Xchar lastc = ' '; /* last char read */
- Xint ttyerr; /* error return from ioctl */
- Xextern int errno; /* system error code */
- Xstruct sgttyb ttybuf; /* local copy of tty control data */
- Xjmp_buf xxx; /* preserved environment for error restart */
- Xint err; /* local error code */
- Xstruct qp t_qp; /* temporary buffer pointer */
- Xstruct qp aa, bb, cc; /* more temporaries */
- Xstruct buffcell t_bcell; /* temporary bcell */
- Xint tabmask = 7; /* mask for typing tabs */
- Xint exitflag; /* flag for ending command str exec */
- Xchar term_char = ESC; /* terminator for insert, search, etc. */
- Xchar cmdc; /* current command character */
- Xchar skipc; /* char found by "skipto()" */
- Xint dot, z, tdot; /* current, last, temp buffer position */
- Xint ins_count; /* count of chars inserted */
- Xint ll, mm, nn; /* general temps */
- Xint ctrl_e = 0; /* form feed flag */
- Xint ctrl_r = 10; /* numeric radix (8, 10, 16) */
- Xint ctrl_s = 0; /* string length for S, I, G */
- Xint ctrl_x = 0; /* search mode flag */
- Xint ed_val = 0; /* ED value */
- Xint es_val = 0; /* ES value */
- Xint et_val = 518; /* ET value */
- Xint eu_val = -1; /* EU value */
- Xint ev_val = 0; /* EV value */
- Xint ez_val = 0; /* EZ value */
- Xint srch_result = 0; /* result of last :S executed */
- Xint atflag = 0; /* flag for @ char typed */
- Xint colonflag = 0; /* flag for : char typed */
- Xint trace_sw = 0; /* nonzero if tracing command exec */
- X
- Xstruct buffcell *insert_p; /* pointer to temp buffer segment during insert */
- Xint buff_mod; /* set to earliest buffer change */
- Xint search_flag; /* set nonzero by search */
- X/* character mapping table (direct) */
- Xchar mapch[] =
- X{
- X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* ^@ - ^M */
- X16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* ^N - ^_ */
- X' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/', /* sp - / */
- X'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', /* 0 - ? */
- X'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* @ - O */
- X'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\',']', '^', '_', /* P - _ */
- X'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* ` - o */
- X'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|','}', '~', 0177 /* p - del */
- X} ;
- X
- X/* character table (mapped to lower case) */
- Xchar mapch_l[] =
- X{
- X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* ^@ - ^M */
- X16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* ^N - ^_ */
- X' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/', /* sp - / */
- X'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', /* 0 - ? */
- X'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* @ - O */
- X'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\',']', '^', '_', /* P - _ */
- X'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* ` - o */
- X'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|','}', '~', 0177 /* p - del */
- X} ;
- X/* table of special characters for "search," "skipto()," and "lines()" */
- X/* see "te_defs.h for meaning of bits */
- X
- Xchar spec_chars[] =
- X{
- X0, A_S, 0, 0, /* ^@ ^A ^B ^C */
- X0, A_A, 0, 0, /* ^D ^E ^F ^G */
- X0, A_T, A_L, A_L, /* ^H ^I ^J ^K */
- XA_L, 0, A_A, 0, /* ^L ^M ^N ^O */
- X0, A_A, A_A, A_A, /* ^P ^Q ^R ^S */
- X0, A_T|A_Q, 0, 0, /* ^T ^U ^V ^W */
- XA_A, 0, 0, 0, /* ^X ^Y ^Z ^[ */
- X0, 0, A_S, 0, /* ^\ ^] ^^ ^_ */
- X0, A_S, A_X, 0, /* ! " # */
- X0, 0, 0, A_X, /* $ % & ' */
- X0, 0, 0, 0, /* ( ) * + */
- X0, 0, 0, 0, /* , - . / */
- X0, 0, 0, 0, /* 0 1 2 3 */
- X0, 0, 0, 0, /* 4 5 6 7 */
- X0, 0, 0, 0, /* 8 9 : ; */
- XA_X, 0, A_X, 0, /* < = > ? */
- XA_S, 0, A_E|A_F, 0, /* @ A B C */
- X0, A_S, A_S, A_Q, /* D E F G */
- X0, A_T|A_E, 0, 0, /* H I J K */
- X0, A_Q, A_T|A_F, A_T, /* L M N O */
- X0, A_Q, A_E, A_T|A_F, /* P Q R S */
- X0, A_Q, 0, A_E, /* T U V W */
- XA_Q, 0, 0, A_Q, /* X Y Z [ */
- X0, A_Q, A_S, A_T|A_E, /* \ ] ^ _ */
- X0, 0, A_E|A_F, 0, /* ` a b c */
- X0, A_S, A_S, A_Q, /* d e f g */
- X0, A_T|A_E, 0, 0, /* h i j k */
- X0, A_Q, A_T|A_F, A_T, /* l m n o */
- X0, A_Q, A_E, A_T|A_F, /* p q r s */
- X0, A_Q, 0, A_E, /* t u v w */
- XA_Q, 0, 0, 0, /* x y z { */
- XA_X, 0, 0, 0, /* | } ~ del */
- X} ;
- X
- END_OF_te_data.c
- if test 7350 -ne `wc -c <te_data.c`; then
- echo shar: \"te_data.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_exec0.c\" \(5458 characters\)
- if test -f te_exec0.c ; then
- echo shar: Will not over-write existing file \"te_exec0.c\"
- else
- sed "s/^X//" >te_exec0.c <<'END_OF_te_exec0.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_exec0.c execute command string 11/31/86 */
- X#include "te_defs.h"
- X#include <sys/time.h>
- X
- Xexec_cmdstr()
- X {
- X char c;
- X int digit_sw;
- X struct tm *timeptr;
- X char *timestring, *asctime();
- X struct timeval timevalue, tzvalue;
- X
- X exitflag = 0; /* set flag to "executing" */
- X cmdstr.p = cbuf.f; /* cmdstr to start of command string */
- X cmdstr.z = cbuf.z;
- X cmdstr.flag = cmdstr.dot = cmdstr.c = 0; /* clear char ptr and iteration flag */
- X msp = &cmdstr; /* initialize macro stack pointer */
- X esp = &estack[0]; /* initialize expression stack pointer */
- X qsp = &qstack[-1]; /* initialize q-reg stack pointer */
- X atflag = colonflag = 0; /* clear flags */
- X esp->flag2 = esp->flag1 = 0; /* initialize expression reader */
- X esp->op = OP_START;
- X trace_sw = 0; /* start out with trace off */
- X digit_sw = 0; /* and no digits read */
- X
- X while (!exitflag) /* until end of command string */
- X {
- X if (getcmdc0(trace_sw) == '^') /* interpret next char as corresp. control char */
- X cmdc = getcmdc(trace_sw) & 0x1f;
- X
- X if (isdigit(cmdc)) /* process number */
- X { /* this works lousy for hex but so does TECO-11 */
- X if (cmdc - '0' >= ctrl_r) ERROR(E_ILN); /* invalid digit */
- X if (!(digit_sw++)) esp->val1 = cmdc - '0'; /* first digit */
- X else esp->val1 = esp->val1 * ctrl_r + cmdc - '0'; /* other digits */
- X esp->flag1++; /* indicate a value read in */
- X }
- X
- X /* not a digit: dispatch on character */
- X
- X else
- X {
- X digit_sw = 0;
- X switch (mapch_l[cmdc])
- X {
- X
- X/* characters ignored */
- X
- X case CR:
- X case LF:
- X case VT:
- X case FF:
- X case ' ':
- X break;
- X/* ESC: one absorbs argument, two terminate current level */
- X
- X case ESC:
- X if (peekcmdc(ESC)) /* if next char is an ESC */
- X {
- X if (msp <= &mstack[0]) exitflag = 1; /* pop stack; if empty, terminate */
- X else --msp;
- X }
- X else
- X {
- X esp->flag1 = 0; /* else consume argument */
- X esp->op = OP_START;
- X }
- X break;
- X
- X/* skip comments */
- X
- X case '!':
- X while (getcmdc(trace_sw) != '!');
- X break;
- X
- X/* modifiers */
- X
- X case '@':
- X atflag++;
- X break;
- X
- X case ':':
- X if (peekcmdc(':')) /* is it "::" ? */
- X {
- X getcmdc(trace_sw); /* yes, skip 2nd : */
- X colonflag = 2; /* and set flag to show 2 */
- X }
- X else colonflag = 1; /* otherwise just 1 colon */
- X break;
- X
- X/* trace control */
- X
- X case '?':
- X trace_sw = !(trace_sw);
- X break;
- X
- X/* values */
- X
- X case '.':
- X esp->val1 = dot;
- X esp->flag1 = 1;
- X break;
- X
- X case 'z':
- X esp->val1 = z;
- X esp->flag1 = 1;
- X break;
- X
- X case 'b':
- X esp->val1 = 0;
- X esp->flag1 = 1;
- X break;
- X case 'h':
- X esp->val1 = z;
- X esp->val2 = 0;
- X esp->flag2 = esp->flag1 = 1;
- X esp->op = OP_START;
- X break;
- X
- X case CTL (S): /* -length of last insert, etc. */
- X esp->val1 = ctrl_s;
- X esp->flag1 = 1;
- X break;
- X
- X case CTL (Y): /* .-^S, . */
- X esp->val1 = dot + ctrl_s;
- X esp->val2 = dot;
- X esp->flag1 = esp->flag2 = 1;
- X esp->op = OP_START;
- X break;
- X
- X case '(':
- X if (++esp > &estack[ESTACKSIZE-1]) ERROR(E_PDO);
- X esp->flag2 = esp->flag1 = 0;
- X esp->op = OP_START;
- X break;
- X
- X case CTL (E): /* form feed flag */
- X esp->val1 = ctrl_e;
- X esp->flag1 = 1;
- X break;
- X
- X case CTL (N): /* eof flag */
- X esp->val1 = infile->eofsw;
- X esp->flag1 = 1;
- X break;
- X
- X case CTL (^): /* value of next char */
- X esp->val1 = getcmdc(trace_sw);
- X esp->flag1 = 1;
- X break;
- X
- X/* date, time */
- X
- X case CTL (B):
- X case CTL (H):
- X gettimeofday(&timevalue, &tzvalue);
- X timeptr = localtime(&timevalue.tv_sec);
- X esp->val1 = (cmdc == CTL (B)) ?
- X timeptr->tm_year * 512 + timeptr->tm_mon * 32 + timeptr->tm_mday :
- X timeptr->tm_hour * 1800 + timeptr->tm_min * 30 + timeptr->tm_sec/2;
- X esp->flag1 = 1;
- X make_buffer(&timbuf); /* make a time buffer */
- X timestring = asctime(timeptr);
- X for (timbuf.z = 0; timbuf.z < 24; timbuf.z++) /* copy character string */
- X timbuf.f->ch[timbuf.z] = *(timestring + timbuf.z);
- X break;
- X/* number of characters to matching ( ) { } [ ] */
- X
- X case CTL (P):
- X do_ctlp();
- X break;
- X
- X/* none of the above: incorporate the last value into the expression */
- X
- X default:
- X if (esp->flag1) /* if a value entered */
- X {
- X switch (esp->op)
- X {
- X case OP_START:
- X break;
- X
- X case OP_ADD:
- X esp->val1 += esp->exp;
- X esp->op = OP_START;
- X break;
- X
- X case OP_SUB:
- X esp->val1 = esp->exp - esp->val1;
- X esp->op = OP_START;
- X break;
- X
- X case OP_MULT:
- X esp->val1 *= esp->exp;
- X esp->op = OP_START;
- X break;
- X
- X case OP_DIV:
- X esp->val1 = (esp->val1) ? esp->exp / esp->val1 : 0;
- X esp->op = OP_START;
- X break;
- X
- X case OP_AND:
- X esp->val1 &= esp->exp;
- X esp->op = OP_START;
- X break;
- X
- X case OP_OR:
- X esp->val1 |= esp->exp;
- X esp->op = OP_START;
- X break;
- X }
- X } /* end of "if a new value" */
- X
- X exec_cmds1(); /* go do the command */
- X } /* end of command dispatch */
- X } /* end of "not a digit" */
- X } /* end of "while" command loop */
- X return;
- X } /* end of exec_cmdstr */
- X
- X
- END_OF_te_exec0.c
- if test 5458 -ne `wc -c <te_exec0.c`; then
- echo shar: \"te_exec0.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_main.c\" \(5907 characters\)
- if test -f te_main.c ; then
- echo shar: Will not over-write existing file \"te_main.c\"
- else
- sed "s/^X//" >te_main.c <<'END_OF_te_main.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_main.c main program 1/14/87 */
- X
- X/*
- X* This is TECO for Ultrix on a Vax. It is mostly compatible with DEC TECO
- X* as explained in the DEC TECO manual. It was written from a manual for
- X* TECO-11 version 34, and so adheres most closely to that version.
- X*
- X* This program consists of several source files, as follows:
- X*
- X* te_main.c (this file) Main program - initialize, read command line and
- X* startup file, handle errors, high-level read and
- X* execute command strings.
- X*
- X* te_defs.h Definitions file, to be #included with other files
- X*
- X* te_data.c Global variables
- X*
- X* te_rdcmd.c Read in a command string
- X*
- X* te_exec0.c First-level command execution - numbers, values,
- X* assemble expressions
- X*
- X* te_exec1.c Most commands
- X*
- X* te_exec2.c "E" and "F" commands, and file I/O
- X*
- X* te_srch.c routines associated with "search" commands
- X*
- X* te_subs.c higher-level subroutines
- X*
- X* te_utils.c lower-level subroutines
- X*
- X* te_chario.c keyboard (stdin), typeout (stdout), suspend
- X*
- X* te_window.c display window and display special functions
- X*
- X* These routines should be compiled and linked to form the TECO executable.
- X*/
- X
- X#include "te_defs.h"
- X
- Xmain(argc, argv)
- X int argc; /* arg count */
- X char *argv[]; /* array of string pointers */
- X {
- X int i;
- X
- X save_args(argc, argv, &qreg[36]); /* copy command line to Qz */
- X read_startup(); /* read startup file */
- X setup_tty(TTY_ON); /* set tty to CBREAK, no echo, asynch mode */
- X window(WIN_INIT); /* initialize screen-image buffer */
- X get_term_par(); /* set terminal screen-size parameters */
- X
- X/* set up error restart */
- X if (err = setjmp(xxx))
- X {
- X if (err == E_EFI) goto quit; /* EOF from standard input - clean up and exit */
- X printf("\015\012? %s", errors[err-1]);
- X if (err == E_SRH) print_string(SERBUF); /* print unfulfilled search string */
- X else if ((err == E_FNF) || (err == E_COF) || (err == E_AMB)) print_string(FILBUF); /* or file string */
- X crlf();
- X eisw = 0; /* stop indirect command execution */
- X et_val &= ~(ET_CTRLC | ET_NOWAIT | ET_CTRLO | ET_NOECHO); /* reset ^C trap, read w/o wait, ^O (unused), no echo */
- X if (et_val & ET_QUIT) /* if ET has "quit on error" set, exit (phone home) */
- X {
- X cleanup(); /* reset screen, keyboard, output files */
- X exit(1); /* and exit */
- X }
- X }
- X
- X/* forever: read and execute command strings */
- X
- X for (exitflag = 1; exitflag >= 0; ) /* "exit" sets exitflag to -1; ^C to -2; "hangup" to -3 */
- X {
- X window(WIN_REFR); /* display the buffer */
- X free_blist(insert_p); /* free any storage from failed insert */
- X free_blist(dly_freebuff); /* return any delayed cells */
- X insert_p = dly_freebuff = NULL;
- X et_val &= ~ET_QUIT; /* clear "abort on error" */
- X if (read_cmdstr()) goto quit;
- X exitflag = 0; /* enable ^C detector */
- X if (!WN_scroll) window(WIN_REDRAW); /* if not in scroll mode, force full redraw on first ^W or nW */
- X exec_cmdstr();
- X }
- X
- X if (exitflag == -2) ERROR(E_XAB); /* ^C detected during execution */
- X else if (exitflag == -3) panic(); /* hangup during execution: save buffer and close files */
- X
- X/* exit from program */
- X
- X quit:
- X ev_val = es_val = 0; /* no last one-line window */
- X window(WIN_REFR); /* last display */
- X cleanup(); /* reset screen, terminal, output files */
- X exit(0); /* and quit */
- X }
- X/* reset screen state, keyboard state; remove open output files */
- X
- Xcleanup()
- X {
- X window(WIN_OFF); /* restore screen */
- X setup_tty(TTY_OFF); /* restore terminal */
- X kill_output(&po_file); /* kill any open primary output file */
- X kill_output(&so_file); /* and secondary file */
- X }
- X
- X
- X/* print string for error message */
- X/* argument is subscript of a qreg qh, prints text from that buffer */
- X
- Xprint_string(arg)
- X int arg;
- X {
- X int i, c;
- X struct buffcell *p;
- X
- X type_char('"');
- X for (p = qreg[arg].f, c = 0, i = 0; i < qreg[arg].z; i++)
- X {
- X if (!p->ch[c]) break;
- X type_char(p->ch[c]);
- X if (++c > CELLSIZE-1)
- X {
- X p = p->f;
- X c = 0;
- X }
- X }
- X type_char('"');
- X }
- X/* copy invocation command line to a text buffer */
- X
- Xsave_args(argc, argv, q)
- X int argc;
- X char *argv[];
- X struct qh *q;
- X {
- X char c;
- X struct qp ptr;
- X
- X make_buffer(q); /* attach a text buffer */
- X ptr.p = q->f; /* initialize pointer to output string */
- X ptr.c = q->z = 0; /* and output char count */
- X for (; argc > 0; argv++, argc--) /* for each arg */
- X {
- X while ( ((c = *((*argv)++)) != '\0') && (q->z < CELLSIZE-1) )
- X {
- X ptr.p->ch[ptr.c] = c; /* copy char to q-reg */
- X fwdcx(&ptr);
- X ++q->z; /* count characters */
- X }
- X if (argc > 1) /* if not last argument... */
- X {
- X ptr.p->ch[ptr.c] = ' '; /* space to separate arguments */
- X fwdcx(&ptr);
- X }
- X }
- X }
- X
- X
- X
- X/* routine to read startup file */
- X
- Xchar startup_name[] = "/.tecorc"; /* name of startup file */
- X
- Xread_startup()
- X {
- X char *hp, *getenv();
- X char fn[CELLSIZE]; /* filename storage */
- X int i;
- X
- X/* look for ".tecorc" in current directory first */
- X
- X if (!(eisw = fopen(&startup_name[1], "r")))
- X {
- X if (hp = getenv("HOME")) /* if not found, look in home directory */
- X {
- X for (i = 0; i < CELLSIZE; i++) if (!(fn[i] = *(hp++))) break; /* copy until trailing null */
- X for (hp = &startup_name[0]; i < CELLSIZE; i++) if (!(fn[i] = *(hp++))) break;
- X eisw = fopen(fn, "r"); /* set eisw if file found, or not if not */
- X }
- X }
- X }
- X/* routine to get terminal height and width from termcap */
- X
- Xget_term_par()
- X {
- X char buff[1024]; /* termcap buffer */
- X char *pname; /* pointer to name of terminal */
- X extern char *getenv();
- X
- X if (pname = getenv("TERM")) /* read terminal name */
- X {
- X tgetent(buff, pname); /* get entry */
- X set_term_par(tgetnum("li"), tgetnum("co")); /* get #lines and #columns and set params */
- X }
- X }
- X
- END_OF_te_main.c
- if test 5907 -ne `wc -c <te_main.c`; then
- echo shar: \"te_main.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_rdcmd.c\" \(7303 characters\)
- if test -f te_rdcmd.c ; then
- echo shar: Will not over-write existing file \"te_rdcmd.c\"
- else
- sed "s/^X//" >te_rdcmd.c <<'END_OF_te_rdcmd.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_rdcmd.c read in the command string 12/20/85 */
- X#include "te_defs.h"
- X
- Xint ccount; /* count of chars read in */
- X
- Xint read_cmdstr()
- X {
- X char c; /* temporary character */
- X int i; /* temporary */
- X
- X goto prompt;
- X
- X restart: /* prompt again: new line */
- X if (!eisw && !inp_noterm) crlf(); /* if input not from a file */
- X prompt: /* issue prompt */
- X if (!eisw && !inp_noterm)
- X {
- X reset_ctlo(); /* reset any ^O */
- X type_char('*');
- X }
- X ccount = 0;
- X lastc = ' ';
- X
- Xreline: /* continue reading */
- X for (;;) /* loop to read command string chars */
- X {
- X if (!eisw && !inp_noterm) /* if terminal input */
- X {
- X if ((c = gettty()) == DEL) /* process rubout */
- X {
- X if (!ccount) goto restart; /* if at beginning, ignore */
- X --ccount; /* decrement char count */
- X backc(&cmdstr); /* back up the command-string pointer */
- X
- X/* look at the character just deleted */
- X if (((c = cmdstr.p->ch[cmdstr.c]) < ' ') && (c != ESC)) /* control chars: set c to char erased */
- X {
- X if (c == LF) vt(VT_LINEUP); /* line up */
- X
- X else if ((c == CR) || (c == TAB))
- X {
- X i = find_lasteol(); /* back up to previous line */
- X type_char(CR); /* erase current line */
- X vt(VT_EEOL);
- X if (i == ccount) type_char('*'); /* if this was line with prompt, retype the prompt */
- X for (; (t_qp.p != cmdstr.p) || (t_qp.c != cmdstr.c); fwdc(&t_qp))
- X type_char(t_qp.p->ch[t_qp.c]); /* retype line: stop before deleted position */
- X }
- X
- X else
- X {
- X vt(VT_BS2); /* erase ordinary ctrl chars */
- X char_count -= 2;
- X }
- X }
- X
- X else
- X {
- X vt(VT_BS1); /* erase printing chars */
- X char_count--;
- X }
- X lastc = ' '; /* disable dangerous last chars */
- X continue;
- X } /* end 'rubout' processing */
- X
- X else if (c == CTL(U)) /* process "erase current line" */
- X {
- X type_char(CR); /* erase line */
- X vt(VT_EEOL);
- X if ((ccount -= find_lasteol()) <= 0) goto prompt; /* back up to last eol: if beginning, restart */
- X cmdstr.p = t_qp.p; /* put command pointer back to this point */
- X cmdstr.c = t_qp.c;
- X lastc = ' ';
- X continue; /* and read it again */
- X }
- X
- X else /* not a rubout or ^U */
- X {
- X if (!ccount) /* if at beginning of line */
- X {
- X if (c == '*') /* save old command string */
- X {
- X type_char('*'); /* echo character */
- X type_char(c = gettty()); /* read reg spec and echo */
- X i = getqspec(0, c);
- X free_blist(qreg[i].f); /* return its previous contents */
- X qreg[i].f = cbuf.f; /* put the old command string in its place */
- X qreg[i].f->b = (struct buffcell *) &qreg[i];
- X qreg[i].z = cbuf.z;
- X cbuf.f = NULL; /* no old command string */
- X err = 0; /* no previous error */
- X goto restart;
- X }
- X else if ((c == '?') && (err)) /* echo previous command string up to error */
- X {
- X type_char('?'); /* echo ? */
- X for (aa.p = cptr.p; aa.p->b->b != NULL; aa.p = aa.p->b); /* find beginning */
- X for (aa.c = 0; (aa.p != cptr.p) || (aa.c < cptr.c); fwdc(&aa)) type_char(aa.p->ch[aa.c]);
- X type_char('?'); /* a final ? */
- X err = 0; /* reset error switch */
- X goto restart;
- X }
- X else if ((c == LF) || (c == CTL (H))) /* line feed, backspace */
- X {
- X dot += lines( (c == LF) ? 1 : -1); /* pointer up or down one line */
- X window(WIN_LINE); /* display one line */
- X goto restart;
- X }
- X
- X else /* first real command on a line */
- X {
- X make_buffer(&cbuf); /* start a command string if need be */
- X cmdstr.p = cbuf.f; /* set cmdstr to point to start of command string */
- X cmdstr.c = 0;
- X cbuf.z = 0; /* no chars in command string now */
- X err = 0; /* clear last error flag */
- X }
- X } /* end of "if first char on line" */
- X
- X
- X/* check ^G-something */
- X
- X if (lastc == CTL (G))
- X {
- X if (c == CTL(G))
- X {
- X cbuf.z = ccount; /* save count for possible "save in q-reg" */
- X goto restart;
- X }
- X if ((c == '*') || (c == ' '))
- X {
- X backc(&cmdstr); /* remove the previous ^G from buffer */
- X --ccount;
- X crlf();
- X retype_cmdstr(c); /* retype appropriate part of command string */
- X lastc = ' ';
- X continue;
- X } /* end of ^G* and ^G<sp> processing */
- X } /* end of "last char was ^G" */
- X } /* end of "not rubout or ^U */
- X } /* end of "if !eisw" */
- X
- X else /* if input from indirect file or redirected std input */
- X {
- X if (!ccount) /* first command? */
- X {
- X if (!cbuf.f) /* start a command string if need be */
- X {
- X cbuf.f = get_bcell();
- X cbuf.f->b = (struct buffcell *) &cbuf;
- X }
- X cmdstr.p = cbuf.f; /* point cmdstr to start of command string */
- X cbuf.z = cmdstr.c = 0;
- X }
- X
- X c = (eisw) ? getc(eisw) : gettty() ; /* get char */
- X if (eisw && (c == EOF)) /* if this is end of the indirect command file */
- X {
- X fclose(eisw); /* close the input file */
- X eisw = 0; /* reset the switch */
- X lastc = ' ';
- X continue; /* and go read more chars */
- X }
- X else
- X {
- X if ((c == LF) && (lastc != CR) && !(ez_val & EZ_CRLF)) /* LF: store implied CR first */
- X {
- X cmdstr.p->ch[cmdstr.c] = CR;
- X ++ccount;
- X fwdcx(&cmdstr);
- X }
- X }
- X } /* end of "if redirected std in or eisw" */
- X
- X
- X/* store character in command string */
- X
- X cmdstr.p->ch[cmdstr.c] = c; /* store the character */
- X ++ccount; /* keep count of chars */
- X if (!eisw && !inp_noterm) type_char(c); /* echo the character */
- X fwdcx(&cmdstr); /* next char pos'n; extend command string if nec */
- X
- X if ((c == ESC) && (lastc == ESC)) break; /* stop on 2nd ESC */
- X if ((c == CTL (C)) && (lastc == CTL (C))) return(-1); /* immediate exit */
- X lastc = c; /* keep track of last char */
- X } /* end of read-char loop */
- X
- X cbuf.z = ccount; /* indicate number of chars in command string */
- X if (!eisw && !inp_noterm) crlf(); /* final new-line */
- X return(0);
- X } /* end of read_cmdstr() */
- X
- X/* back up to find most recent CR or LF in entered command string */
- X/* return number of chars backed up */
- X
- Xint find_lasteol()
- X {
- X int i;
- X
- X for (i = 0, t_qp.p = cmdstr.p, t_qp.c = cmdstr.c; (backc(&t_qp)) ; i++) /* look for beg. of line */
- X {
- X if ((t_qp.p->ch[t_qp.c] == CR) || (t_qp.p->ch[t_qp.c] == LF))
- X {
- X fwdc(&t_qp); /* stop short of previous eol */
- X break;
- X }
- X }
- X char_count = 0; /* reset tab count */
- X return(i);
- X }
- X
- X
- X
- X/* retype command string: entirely (arg = '*') or most recent line (arg = ' ') */
- X
- Xretype_cmdstr(c)
- X char c;
- X {
- X int i;
- X
- X if (!inp_noterm) /* if input is really from terminal */
- X {
- X if (c == ' ') /* look for beginning of this line */
- X i = ccount - find_lasteol(); /* to last eol, and count char's backed up */
- X else
- X {
- X t_qp.p = cbuf.f; /* retype whole command string */
- X i = t_qp.c = 0;
- X }
- X if (!i) type_char('*'); /* if from beginning, retype prompt */
- X for (; i < ccount; i++) /* type command string from starting point */
- X {
- X type_char(t_qp.p->ch[t_qp.c]);
- X fwdc(&t_qp);
- X }
- X }
- X }
- X
- END_OF_te_rdcmd.c
- if test 7303 -ne `wc -c <te_rdcmd.c`; then
- echo shar: \"te_rdcmd.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_utils.c\" \(5967 characters\)
- if test -f te_utils.c ; then
- echo shar: Will not over-write existing file \"te_utils.c\"
- else
- sed "s/^X//" >te_utils.c <<'END_OF_te_utils.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_utils.c utility subroutines 10/28/85 */
- X
- X#include "te_defs.h"
- X
- X/* routines to handle storage */
- X/* get a buffcell */
- X/* if there are no buffcells available, call malloc for more storage */
- X
- Xstruct buffcell *get_bcell()
- X {
- X char *malloc();
- X struct buffcell *p;
- X int i;
- X
- X if (freebuff == NULL)
- X {
- X p = (struct buffcell *) malloc(BLOCKSIZE);
- X if (!p) ERROR(E_MEM);
- X else
- X {
- X freebuff = p; /* take the given address as storage */
- X for (i = 0; i < (BLOCKSIZE/sizeof(struct buffcell)) - 1; i++) /* for all cells in the new block */
- X (p+i)->f = p+i+1; /* chain the forward pointers together */
- X (p+i)->f = NULL; /* make the last one's forward pointer NULL */
- X }
- X }
- X
- X p = freebuff; /* cut out head of "free" list */
- X freebuff = freebuff->f;
- X p->f = p->b = NULL;
- X return(p);
- X }
- X
- X
- X/* free a list of buffcells */
- Xfree_blist(p)
- X struct buffcell *p;
- X {
- X struct buffcell *t;
- X
- X if (p != NULL)
- X {
- X for (t = p; t -> f != NULL; t = t -> f); /* find end of ret'd list */
- X t->f = freebuff; /* put ret'd list at head of "free" list */
- X freebuff = p;
- X }
- X }
- X/* free a list of buffcells to the "delayed free" list */
- Xdly_free_blist(p)
- X struct buffcell *p;
- X {
- X struct buffcell *t;
- X
- X if (p != NULL)
- X {
- X for (t = p; t -> f != NULL; t = t -> f); /* find end of ret'd list */
- X t->f = dly_freebuff; /* put ret'd list at head of "free" list */
- X dly_freebuff = p;
- X }
- X }
- X
- X
- X
- X/* get a cell */
- X/* if there are no cells available, get a buffcell and make more */
- X
- Xstruct qp *get_dcell()
- X {
- X struct qp *t;
- X int i;
- X
- X if (freedcell == NULL)
- X {
- X t = freedcell = (struct qp *) get_bcell(); /* get a buffcell */
- X for (i = 0; i < (sizeof(struct buffcell)/sizeof(struct qp)) - 1; i++)
- X {
- X (t+i)->f = t+i+1; /* chain the fwd pointers together */
- X (t+i)->f = NULL; /* make the last one's forward pointer NULL */
- X }
- X }
- X
- X t = freedcell; /* cut out head of "free" list */
- X freedcell = (struct qp *) freedcell->f;
- X t->f = NULL;
- X return(t);
- X }
- X
- X
- X/* free a list of cells */
- Xfree_dlist(p)
- X struct qp *p;
- X {
- X struct qp *t;
- X
- X if (p != NULL)
- X {
- X for (t = p; t->f != NULL; t = t->f); /* find end of ret'd list */
- X t->f = freedcell; /* put ret'd list at head of "free" list */
- X freedcell = p;
- X }
- X }
- X/* build a buffer: called with address of a qh */
- X/* if no buffer there, get a cell and link it in */
- Xmake_buffer(p)
- X struct qh *p;
- X {
- X if (!(p->f))
- X {
- X p->f = get_bcell();
- X p->f->b = (struct buffcell *) p;
- X }
- X }
- X
- X
- X/* routines to advance one character forward or backward */
- X/* argument is the address of a qp */
- X/* fwdc, backc return 1 if success, 0 if beyond extremes of buffer) */
- X/* fwdcx extends buffer if failure */
- X
- Xint fwdc(arg)
- X struct qp *arg;
- X {
- X if ((*arg).c >= CELLSIZE-1) /* test char count for max */
- X {
- X if ((*arg).p->f == NULL) return(0); /* last cell: fail */
- X else
- X {
- X (*arg).p = (*arg).p->f; /* chain through list */
- X (*arg).c = 0; /* and reset char count */
- X }
- X }
- X else ++(*arg).c; /* otherwise just incr char count */
- X ++(*arg).dot;
- X return(1);
- X }
- X
- Xfwdcx(arg)
- X struct qp *arg;
- X {
- X if ((*arg).c >= CELLSIZE-1) /* test char count for max */
- X {
- X if ((*arg).p->f == NULL) /* last cell: extend */
- X {
- X (*arg).p->f = get_bcell();
- X (*arg).p->f->b = (*arg).p;
- X }
- X (*arg).p = (*arg).p->f; /* chain through list */
- X (*arg).c = 0; /* and reset char count */
- X }
- X else ++(*arg).c; /* otherwise just incr char count */
- X ++(*arg).dot;
- X return(1);
- X }
- Xint backc(arg)
- X struct qp *arg;
- X {
- X if ((*arg).c <= 0) /* test char count for min */
- X {
- X if ((*arg).p->b->b == NULL) return(0); /* first cell: fail */
- X else
- X {
- X (*arg).p = (*arg).p->b; /* chain through list */
- X (*arg).c = CELLSIZE-1; /* reset char count */
- X }
- X }
- X else --(*arg).c; /* otherwise just decr char count */
- X --(*arg).dot;
- X return(1);
- X }
- X
- X
- X/* set up a pointer to a particular text buffer position */
- X
- Xset_pointer(pos, ptr) /* first arg is position, 2nd is addr of pointer */
- X int pos;
- X struct qp *ptr;
- X {
- X struct buffcell *t;
- X int i;
- X
- X if (!buff.f)
- X {
- X buff.f = get_bcell(); /* if no text buffer, make one */
- X buff.f->b = (struct buffcell *) &buff;
- X }
- X for (i = pos/CELLSIZE, t = buff.f; (i > 0) && (t->f != NULL); i--) t = t->f;
- X ptr->p = t;
- X ptr->c = pos % CELLSIZE;
- X ptr->dot = pos;
- X ptr->z = z;
- X }
- X/* routines to get next character from command buffer */
- X/* getcmdc0, when reading beyond command string, pops */
- X/* macro stack and continues. */
- X/* getcmdc, in similar circumstances, reports an error */
- X/* if pushcmdc() has returned any chars, read them first */
- X/* routines type characters as read, if argument != 0 */
- X
- Xchar getcmdc0(trace)
- X {
- X while (cptr.dot >= cptr.z) /* if at end of this level, pop macro stack */
- X {
- X if (--msp < &mstack[0]) /* pop stack; if top level */
- X {
- X msp = &mstack[0]; /* restore stack pointer */
- X cmdc = ESC; /* return an ESC (ignored) */
- X exitflag = 1; /* set to terminate execution */
- X return(cmdc); /* exit "while" and return */
- X }
- X }
- X cmdc = cptr.p->ch[cptr.c++]; /* get char */
- X ++cptr.dot; /* increment character count */
- X if (trace) type_char(cmdc); /* trace */
- X if (cptr.c > CELLSIZE-1) /* and chain if need be */
- X {
- X cptr.p = cptr.p->f;
- X cptr.c = 0;
- X }
- X return(cmdc);
- X }
- X
- X
- Xchar getcmdc(trace)
- X {
- X if (cptr.dot++ >= cptr.z) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X else
- X {
- X cmdc = cptr.p->ch[cptr.c++]; /* get char */
- X if (trace) type_char(cmdc); /* trace */
- X if (cptr.c > CELLSIZE-1) /* and chain if need be */
- X {
- X cptr.p = cptr.p->f;
- X cptr.c = 0;
- X }
- X }
- X return(cmdc);
- X }
- X
- X
- X/* peek at next char in command string, return 1 if it is equal (case independent) to argument */
- Xint peekcmdc(arg)
- X char arg;
- X {
- X return(((cptr.dot < cptr.z) && (mapch_l[cptr.p->ch[cptr.c]] == mapch_l[arg])) ? 1 : 0);
- X }
- X
- END_OF_te_utils.c
- if test 5967 -ne `wc -c <te_utils.c`; then
- echo shar: \"te_utils.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"teco.doc\" \(7799 characters\)
- if test -f teco.doc ; then
- echo shar: Will not over-write existing file \"teco.doc\"
- else
- sed "s/^X//" >teco.doc <<'END_OF_teco.doc'
- XTECO for Ultrix Matt Fichtenbaum January 12, 1987
- X
- X This TECO is almost compatible with "Standard TECO" as described in
- XDEC literature. It differs in its display support and interaction with the
- Xoperating system, and in the omission of a few less-frequently-used features.
- XA few of its features are extensions not found in Standard TECO.
- X
- X The following is a brief comparison between this TECO and Standard
- XTECO version 34, the last for which I have notes.
- X
- X
- XMissing features:
- X
- X ^F (console switch register)
- X EG (exit and execute system command)
- X EH (help flag)
- X EO (version)
- X ET & 16 (cancel ^O on output)
- X ET & 64 (detach)
- X EU (upper/lower case flag)
- X backward paging in file (negative arguments to P, N, etc.)
- X
- X
- XNew features:
- X
- X EQtext$ pass "text" as a command to the shell. The command is executed
- X or in a Unix subshell, with standard input, output, and error
- X @EQ/text/ connected to the terminal (i.e., unchanged from TECO's setup).
- X
- X nEQtext$ pass "text" as a command to the shell. The command is executed
- X or in a Unix subshell. The command's standard input is the
- X m,nEQtext$ specified text ("n" lines or "m,n" characters) from TECO's
- X (and "@" buffer, and its standard output replaces the text in q-register
- X forms) q#. This form of the EQ command thus passes text from TECO's
- X buffer through a Unix command and makes the result available to
- X TECO. (The pointer is left after the specified text and ^S is
- X set appropriately, so ^SDG# after m,nEQcommand$ replaces the
- X original text with the command's output)
- X
- X EQ commands execute same command as previous EQ. The presence of arguments
- X with empty specifies the command's standard input and output, as above.
- X string (EQ$)
- X
- X ^P if the pointer is positioned on one of the characters
- X ( ) { } [ ] < > " ' then ^P has the value of the number
- X of characters to the matching character. Otherwise ^P has
- X value 0. Thus ^PC performs the same function as "%" in vi.
- X (Note: " is considered to match ' )
- X
- X Q% buffer containing last Unix command string from EQ command
- X
- X Q# buffer containing ASCII text from Unix. After the commands
- X "nEQ" and "m,nEQ" this is the standard output from the
- X invoked command; after ^B or ^H this is the date and time
- X expressed as a character string.
- X
- X Text buffer of arbitrary size, using Ultrix virtual memory.
- X EZ word with some unrelated one-bit flags, as follows:
- X
- X 1 0: read Unix files: '\n' in file becomes <CR><LF> in
- X TECO buffer, converted back to '\n' on write.
- X 1: read files literally without this conversion.
- X
- X 2 0: read from file terminates on form feed or EOF
- X 1: read terminates on EOF only; FFs are put into the buffer
- X
- X 4 0: tabs are displayed every 8 columns
- X 1: tabs are displayed every 4 columns
- X
- X 8 0: EWfile$ and EBfile$ open "file.tmp" as output file;
- X this is renamed to "file" when output file is closed.
- X 1: EWfile$ opens "file" as named - any preexisting file
- X of this name is immediately deleted. EBfile$ always
- X opens "file.tmp."
- X (This form must be used when the output is to a non-
- X directory device, e.g. /dev/tty)
- X
- X 16 0: <TAB>text$ inserts a tab, then text
- X 1: <TAB> is ignored as a command
- X
- X 32 0: <LF>, <FF> and <VT> count as line separators for commands
- X that count lines (nL, nXq, etc.)
- X 1: only <LF> counts as a line separator
- X
- X 64 0: ER or EB commands that specify multiple files cause an error
- X 1: These commands open the first specified files; other files
- X may be accessed with the EN$ command (see File Expansion, below)
- X
- X
- XThings that work differently
- X
- X startup this TECO looks for a file called ".tecorc" in the user's
- X home directory and then in the current directory. TECO
- X does no processing of command line arguments, but the
- X entire command line is passed to .tecorc in Q-register Z.
- X .tecorc may treat the command line as it wishes.
- X
- X EB EBfile$ opens "file.tmp" for output. When the file is
- X successfully closed (EC, EF, EX), the original file is
- X renamed with a ".bak" suffix and the ".tmp" file is
- X renamed with the original name (see bit "8" of variable EZ).
- X
- X ED & 4 When this bit is set, a command that reads the input file
- X (P, Y, A) stops reading when the number of characters in
- X the buffer exceeds 16384. When this bit is clear, the
- X buffer is expanded without limit.
- X
- X EN ENtext$ or @EN/text/ specifies a file specification that is
- X passed to the shell for expansion into one or more file names.
- X EN$ or @EN//, with no string specified, fetches the next file
- X name into the filespec buffer. If there are no more files
- X :EN returns 0, EN causes an error.
- X Filename When specified in ER or EB commands, filenames that begin with
- X expansion the character ~, or that contain any of the characters * ? { [,
- X are passed to the shell to be expanded. If exactly one file
- X matches the specification this file is opened. If more than one
- X file matches, the action depends on the setting of bit 64 in
- X variable EZ: if this bit is 0, TECO reponds with an "ambiguous
- X file specification" error; if this bit is 1, TECO substitutes
- X the list of files for the list resulting from the last EN command,
- X if any, and opens the first file on the list. Subsequent entries on
- X this list are fetched to the filespec buffer by the EN$ command,
- X as above. EW (output) and EI (indirect command execution) commands
- X are not expanded in this manner.
- X
- X window this TECO's window support is hard-coded for a VT100-type
- X terminal. It includes many but not all of the window
- X functions of Standard TECO. The following is a summary of
- X the display features:
- X
- X 0:w (terminal type) always 4 (VT100 in ANSI mode)
- X 1:w (terminal width) obtained from Ultrix at startup
- X 2:w (terminal height) obtained from Ultrix at startup
- X 3:w (seeall mode) unimplemented
- X 4:w (mark) unimplemented
- X 5:w (hold mode) unimplemented
- X 6:w (screen origin) read-only parameter
- X 7:w (split-screen mode) implemented
- X
- X ^W immediate absolute window redraw
- X
- X nW (n not 0 or -1000) immediate window redraw, incremental
- X unless other output commands have been executed and scroll
- X mode was disabled
- X
- X -1000W "forget" that output has occurred
- X
- X Note: window functions using other "special" values as arguments
- X to nW are not implemented.
- X
- X EV, ES argument to these is the number of lines to display
- X (nEV displays 2N-1 lines about the line containing
- X the pointer). The character at the pointer is
- X shown in reverse video.
- X
- X
- XInteractions with Ultrix
- X
- X Terminal I/O uses stdin and stdout; numerous ioctl's are used to
- Xadjust the terminal driver's modes. File I/O uses the buffered I/O
- Xfunctions of <stdio.h>.
- X
- X The time (^H) and date (^B) make use of the system call
- X"gettimeofday" (2).
- X
- X The EQ and EN commands and the expansion of filenames for the ER
- Xand EB commands spawn child processes that use pipes for interprocess
- Xcommunication.
- X Teco explicitly handles the following signals:
- X
- X SIGINT (interrupt) The "interrupt" character (^C or equivalent)
- X interrupts an executing Teco command string or macro, and
- X gives the error "Execution interrupted." When no command
- X string is executing this character is not treated specially.
- X
- X SIGTSTP (suspend) Teco responds to this signal by restoring
- X the terminal characteristics to their original values and
- X then suspending itself.
- X
- X SIGHUP (hangup) Teco responds to this signal by attempting
- X to save the text buffer and any open output files before
- X exiting. If there is any text in the buffer, it is written
- X to the currently- selected output file; if there is no file,
- X the buffer is written to the file TECO_SAVED.tmp. Any open
- X output files are closed, retaining their ".tmp" suffixes.
- X Unread input is not copied to the output files.
- X
- END_OF_teco.doc
- if test 7799 -ne `wc -c <teco.doc`; then
- echo shar: \"teco.doc\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"teco_data.doc\" \(4567 characters\)
- if test -f teco_data.doc ; then
- echo shar: Will not over-write existing file \"teco_data.doc\"
- else
- sed "s/^X//" >teco_data.doc <<'END_OF_teco_data.doc'
- XA few quick comments on the ways teco arranges its internal
- Xdata storage
- X
- X Teco has two classes of buffer:
- X 1. Text buffer (the text buffer, q-registers, the command string)
- X 2. Other (buffer header, buffer pointer, iteration-stack entry)
- X
- X
- XText buffers
- X
- X Each text buffer is a linked list of cells; this is a convenient
- Xway to divide a single address space among an arbitrary number of
- Xbuffers of arbitrary size. Each cell ("struct buffcell") contains a
- Xforward pointer, a backward pointer, and an array of characters.
- XThe teco buffer, each q-register, each entry on the q-register
- Xpushdown list, and the command string are lists of these cells.
- X
- X Teco maintains a list of free buffer cells, and its storage
- Xallocation routines furnish cells when needed and accept returned
- Xones. If the list of free cells is empty, teco calls malloc() to
- Xget a block of storage which it then divides into cells. Teco never
- Xreturns the storage it gets from malloc().
- X
- X The text buffer is kept in packed form: each cell but the last
- Xcontains the full number of characters. This makes it easy for teco
- Xto find its way through the buffer but increases the time taken by
- Xinsert and delete. It might be interesting to add a "count" field
- Xto the buffer cell and allow cells within the buffer to have empty
- Xspaces at the end; this is a possible future modification.
- X
- X
- XOther
- X
- X Teco uses three types of small data cell - the q-register header
- X("struct qh"), the q-register pointer ("struct qp"), and the macro
- Xiteration list entry ("struct is"). Although defined as separate
- Xstructures, these are really the same basic cell: they are kept as
- Xa list of free cells and cast to the proper definition when needed.
- X
- X As in the case of text-buffer cells, data cells are supplied by and
- Xreturned to teco's storage allocation routines. When a data cell is
- Xneeded and no free cells are available, the storage allocator obtains
- Xa text buffer cell and carves it up into smaller cells, thus, the text-
- Xbuffer cell system is the only interface to malloc().
- X
- X A text-buffer header ("struct qh") consists of a forward pointer that
- Xpoints to the first cell of the buffer, a backward pointer that is NULL,
- Xa count of characters, and an integer value - the "value" of a numeric
- Xq-register. The teco buffer has a named header named buff; the q-registers
- Xhave an array, named qreg[], of headers.
- X
- X NOTE that the "struct qh" and the "struct buffcell" begin
- X identically: the forward and backward pointers are in
- X the same locations in both structures. Teco uses this in
- X handling lists: because the buffer header appears to be a
- X buffer cell, inserting a cell at the beginning of a list is
- X the same as inserting one farther down. This is probably a
- X bad implementation and may not work on all machines.
- X
- X A q-register pointer ("struct qp") points to a place within a text
- Xbuffer or q-register or the command string. It has a pointer to the
- Xcurrent buffer cell, a value of the current character within the cell,
- Xvalues for the number of characters in the buffer and the number of the
- Xcurrent character, and, if it is a macro-stack entry, a pointer to the
- Xiteration stack for that macro.
- X
- X A number of q-register pointers are used as general temporaries, for
- Xmoving text within the buffer, outputting text, etc. A stack of these
- Xpointers, the macro stack mstack[], controls the execution of command
- Xstrings and macros. The stack's first entry always points to the command
- Xstring, and a new entry is pushed each time a macro is invoked and is
- Xpopped when the macro terminates.
- X
- X An iteration-stack entry ("struct is") maintains the data needed for
- Xcommand-string or macro iteration. Each command or macro level can
- Xhave an iteration stack associated with it: this is kept as a linked
- Xlist of iteration-stack entries, and the macro stack entry contains a
- Xpointer to the head of the list. Each iteration-stack entry contains
- Xforward and backward pointers for the iteration stack, a pointer
- X(cell address, character offset, absolute character count) to the
- Xcommand that starts the iteration, a count of iterations remaining,
- Xand a flag for definite/indefinite iteration.
- X
- X An iteration stack is created for a particular command or macro level
- Xthe first time that a loop is encountered at that level. The cells of
- Xthe stack are not reclaimed but are reused the next time an iteration
- Xoccurs at that command level.
- X
- X The data definitions specify two more data-structure types, a macro
- Xstack entry ("struct ms") and a buffer header list entry ("struct bh").
- XThese are not used at present.
- X
- END_OF_teco_data.doc
- if test 4567 -ne `wc -c <teco_data.doc`; then
- echo shar: \"teco_data.doc\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 1 \(of 4\).
- cp /dev/null ark1isdone
- DONE=true
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- echo shar: You still need to run archive ${I}.
- DONE=false
- fi
- done
- if test "$DONE" = "true" ; then
- echo You have unpacked all 4 archives.
- echo "See the *.doc files"
- rm -f ark[1-9]isdone
- fi
- ## End of shell archive.
- exit 0
-